# 导入HttpResponse类，用于处理HTTP响应
from django.http import HttpResponse
# 导入MiddlewareMixin类，用于创建中间件
from django.utils.deprecation import MiddlewareMixin
# 导入JWT相关的异常类，用于处理JWT验证过程中的各种异常
from jwt import ExpiredSignatureError, InvalidTokenError, PyJWTError
# 导入SimpleJWT的认证后端
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from rest_framework_simplejwt.tokens import AccessToken
from .models import SysUser
import json


class JwtAuthenticationMiddleware(MiddlewareMixin):
    """
    JWT认证中间件 - 适配SysUser模型
    """

    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        在视图处理前进行JWT认证
        :param request: 请求对象
        :param view_func: 视图函数
        :param view_args: 视图参数
        :param view_kwargs: 视图关键字参数
        :return: HttpResponse对象或None
        """
        # 请求白名单
        white_list = ["/user/login/", "/user/register/", "/user/logout/"]
        path = request.path
        
        # 对不在白名单内且不是媒体资源的请求进行token验证
        if path not in white_list and not path.startswith("/media"):
            # 从Request Header中获取token
            auth_header = request.META.get('HTTP_AUTHORIZATION')
            
            if not auth_header:
                return self._create_error_response('缺少认证令牌！', 401)
            
            try:
                # 检查是否以'Bearer '开头
                if not auth_header.startswith('Bearer '):
                    return self._create_error_response('Token格式错误！', 401)
                
                # 获取token字符串
                token_str = auth_header.split(' ')[1]
                
                # 验证token
                access_token = AccessToken(token_str)
                user_id = access_token['user_id']
                
                # 确保 user_id 是整数
                if isinstance(user_id, str):
                    user_id = int(user_id)
                
                # 获取用户对象
                try:
                    user = SysUser.objects.get(id=user_id)
                    if not user.is_active:
                        return self._create_error_response('用户已被停用！', 401)
                    
                    # 设置用户到请求对象的自定义属性，避免被DRF覆盖
                    request._jwt_user = user
                    request.user = user  # 也设置到标准属性，以防有其他地方需要
                    
                except SysUser.DoesNotExist:
                    return self._create_error_response('用户不存在！', 401)
                    
            except (InvalidToken, TokenError) as e:
                return self._create_error_response(f'Token验证失败: {str(e)}', 401)
            except Exception as e:
                return self._create_error_response('Token验证异常！', 401)
                
        else:
            # 白名单内的请求或媒体资源，无需token验证
            return None
    
    def _create_error_response(self, message, status_code):
        """
        创建错误响应
        """
        response_data = {
            'code': status_code,
            'message': message
        }
        return HttpResponse(
            json.dumps(response_data, ensure_ascii=False),
            status=status_code,
            content_type='application/json; charset=utf-8'
        )
